package com.flyduck.vueshop.auth.h5.service.impl;

import cn.hutool.crypto.SecureUtil;
import com.flyduck.vueshop.auth.constant.AuthConstant;
import com.flyduck.vueshop.auth.h5.service.H5LoginService;
import com.flyduck.vueshop.auth.h5.vo.H5CaptchaRespVO;
import com.flyduck.vueshop.auth.h5.vo.H5LoginReqVO;
import com.flyduck.vueshop.auth.h5.vo.H5LoginRespVO;
import com.flyduck.vueshop.auth.h5.vo.H5RegisterReqVO;
import com.flyduck.vueshop.common.core.exception.BusinessException;
import com.flyduck.vueshop.common.core.utils.BeanUtils;
import com.flyduck.vueshop.common.redis.utils.RedisUtils;
import com.flyduck.vueshop.common.sotoken.utils.StpUserUtil;
import com.flyduck.vueshop.user.vo.RemoteUserRespVO;
import com.flyduck.vueshop.user.vo.RemoteUserSaveReqVO;
import com.flyduck.vueshop.user.vo.RemoteUserUpdateReqVO;
import com.flyduck.vueshop.user.feign.RemoteUserFeignClient;
import com.google.code.kaptcha.Producer;
import org.springframework.stereotype.Service;
import sun.misc.BASE64Encoder;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.UUID;

/**
 * <p>
 * H5LoginServiceImpl
 * </p>
 *
 * @author flyduck
 * @since 2024-07-10
 */
@Service
public class H5LoginServiceImpl implements H5LoginService {
    @Resource
    private RemoteUserFeignClient remoteUserFeignClient;
    @Resource
    private Producer producer;
    @Resource
    private RedisUtils redisUtils;

    @Override
    public H5LoginRespVO login(H5LoginReqVO h5LoginReqVO) {
        //校验用户名密码
        RemoteUserRespVO remoteUserRespVO = remoteUserFeignClient.getUserByUsername(h5LoginReqVO.getUsername()).getData();
        if(remoteUserRespVO == null){
            throw new BusinessException("用户不存在");
        }
        if (!remoteUserRespVO.getPassword().equals(SecureUtil.md5(h5LoginReqVO.getPassword()))) {
            throw new BusinessException("密码错误");
        }

        //更新最后登录时间
        RemoteUserUpdateReqVO remoteUserUpdateReqVO = BeanUtils.toBean(remoteUserRespVO, RemoteUserUpdateReqVO.class);
        remoteUserUpdateReqVO.setLastLogin(LocalDateTime.now());
        remoteUserFeignClient.updateUser(remoteUserUpdateReqVO);

        //生成token
        StpUserUtil.login(remoteUserRespVO.getId());
        String token = StpUserUtil.getTokenValue();

        H5LoginRespVO.AppUserVO appUserVO = BeanUtils.toBean(remoteUserRespVO, H5LoginRespVO.AppUserVO.class);
        H5LoginRespVO h5LoginRespVO = new H5LoginRespVO();
        h5LoginRespVO.setToken(token);
        h5LoginRespVO.setUserInfo(appUserVO);
        return h5LoginRespVO;
    }

    @Override
    public H5CaptchaRespVO getCaptcha() {
        //生成uuid和验证码
        String uuid = UUID.randomUUID().toString();
        String code = producer.createText();

        //生成base64编码的图片验证码
        BufferedImage image = producer.createImage(code);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            ImageIO.write(image, "jpg", outputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }

        BASE64Encoder encoder = new BASE64Encoder();
        String base64Img = "data:image/jpeg;base64," + encoder.encode(outputStream.toByteArray());

        //把uuid和验证码存储到redis
        redisUtils.set(AuthConstant.RedisKeyConstant.APP_CAPTCHA_PREFIX + uuid, code,120);


        //返回uuid和base64图片
        H5CaptchaRespVO h5CaptchaRespVO = new H5CaptchaRespVO();
        h5CaptchaRespVO.setUuid(uuid);
        h5CaptchaRespVO.setBase64Img(base64Img);
        return h5CaptchaRespVO;
    }

    @Override
    public void register(H5RegisterReqVO h5RegisterReqVO) {
        //验证验证码是否正确
        Object redisCode = redisUtils.get(AuthConstant.RedisKeyConstant.APP_CAPTCHA_PREFIX + h5RegisterReqVO.getUuid());
        if(!h5RegisterReqVO.getCode().equals(redisCode)){
            throw new BusinessException("验证码错误");
        }

        //判断用户名是否已经存在
        RemoteUserRespVO remoteUserRespVO = remoteUserFeignClient.getUserByUsername(h5RegisterReqVO.getUsername()).getData();
        if(remoteUserRespVO != null){
            throw new BusinessException("用户不存在");
        }

        //注册用户
        RemoteUserSaveReqVO remoteUserSaveReqVO = new RemoteUserSaveReqVO();
        remoteUserSaveReqVO.setUsername(h5RegisterReqVO.getUsername());
        remoteUserSaveReqVO.setPassword(SecureUtil.md5(h5RegisterReqVO.getPassword()));
        remoteUserSaveReqVO.setCreated(LocalDateTime.now());
        remoteUserFeignClient.saveUser(remoteUserSaveReqVO);
    }
}
